﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Networking;
using System.Windows.Forms;

namespace PacketTest
{
    /// <summary>
    /// Summary description for PacketTest
    /// </summary>
    [TestClass]
    public class PacketTest
    {
        public PacketTest()
        {
            //
            // TODO: Add constructor logic here
            //          

        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void TestAutenticationResponse()
        {
            AutenticationResponsePacket snd = new AutenticationResponsePacket(1000);

            byte[] buffer = snd.Serialize();

            AutenticationResponsePacket rcv = new AutenticationResponsePacket(buffer);

            Assert.IsTrue(rcv.CheckChallenge(1000), "The AutenticationResponsePacket corrups the encoded challenge response");

            //Assert.AreEqual(1000, rcv.CheckChallenge, "The AutenticationResponsePacket corrups the encoded challenge response");

        }


        [TestMethod]
        public void TestAutentication()
        {

            {
                AutenticationPacket snd = new AutenticationPacket(1000);

                byte[] buffer = snd.Serialize();

                AutenticationPacket rcv = new AutenticationPacket(buffer);

                Assert.AreEqual(1000, rcv.Challenge, "The AutenticationPacket corrupts the challenge");
            }

            {
                AutenticationPacket snd = new AutenticationPacket();

                int i = snd.Challenge;

                byte[] buffer = snd.Serialize();

                AutenticationPacket rcv = new AutenticationPacket(buffer);

                Assert.AreEqual(i, rcv.Challenge, "The random challenge (" + i + ") got corrupted during serialize/deserialize");

            }


        }

        [TestMethod]
        public void TestAckNack()
        {
            {
                AckNackPacket snd = new AckNackPacket(true);

                byte[] buffer = snd.Serialize();

                AckNackPacket rcv = new AckNackPacket(buffer);

                Assert.AreEqual(true, rcv.IsOK, "The AckNackPacket doesnt correctly serialize/deserialize ack condition");
            }

            {
                AckNackPacket snd = new AckNackPacket(false);

                byte[] buffer = snd.Serialize();

                AckNackPacket rcv = new AckNackPacket(buffer);

                Assert.AreEqual(false, rcv.IsOK, "The AckNackPacket doesnt correctly serialize/deserialize Nack condition");
            }


        }

        [TestMethod]
        public void TestPointerEvent()
        {
            {

                PointerEventPacket snd = new PointerEventPacket(true, true, true, true, true, new Coords(100, 200));

                byte[] buffer = snd.Serialize();

                PointerEventPacket rcv = new PointerEventPacket(buffer);

                Assert.AreEqual(true, rcv.LeftButton, "Left button state corrupted");
                Assert.AreEqual(true, rcv.MiddleButton, "Middle button state corrupted");
                Assert.AreEqual(true, rcv.RightButton, "Right button state corrupted");
                Assert.AreEqual(true, rcv.WheelUp, "WheelUp button state corrupted");
                Assert.AreEqual(true, rcv.WheelDown, "WheelDown button state corrupted");

                Assert.AreEqual(100, rcv.Coords.X, "The X coord is corrupted");
                Assert.AreEqual(200, rcv.Coords.Y, "The Y coord is corrupted");
            }

            {

                PointerEventPacket snd = new PointerEventPacket(false, false, false, false, false, new Coords(200, 300));

                byte[] buffer = snd.Serialize();

                PointerEventPacket rcv = new PointerEventPacket(buffer);

                Assert.AreEqual(false, rcv.LeftButton, "Left button state corrupted");
                Assert.AreEqual(false, rcv.MiddleButton, "Middle button state corrupted");
                Assert.AreEqual(false, rcv.RightButton, "Right button state corrupted");
                Assert.AreEqual(false, rcv.WheelUp, "WheelUp button state corrupted");
                Assert.AreEqual(false, rcv.WheelDown, "WheelDown button state corrupted");

                Assert.AreEqual(200, rcv.Coords.X, "The X coord is corrupted");
                Assert.AreEqual(300, rcv.Coords.Y, "The Y coord is corrupted");
            }

        }

        [TestMethod]
        public void TestKeyEvent()
        {

            {

                KeyEventPacket snd = new KeyEventPacket(true, Keys.A);

                byte[] buffer = snd.Serialize();

                KeyEventPacket rcv = new KeyEventPacket(buffer);

                Assert.AreEqual(true, rcv.DownFlag, "DownFlag status corrupted");
                Assert.AreEqual(Keys.A, rcv.Key, "Key number corrupted");

            }

            {

                KeyEventPacket snd = new KeyEventPacket(false, Keys.O);

                byte[] buffer = snd.Serialize();

                KeyEventPacket rcv = new KeyEventPacket(buffer);

                Assert.AreEqual(false, rcv.DownFlag, "DownFlag status corrupted");
                Assert.AreEqual(Keys.O, rcv.Key, "Key number corrupted");

            }


        }

        [TestMethod]
        public void TestFramebufferUpdateRequest()
        {

            {
                FramebufferUpdateRequestPacket snd = new FramebufferUpdateRequestPacket(4, new Coords(200, 300), new Size(100, 50));

                byte[] buffer = snd.Serialize();

                FramebufferUpdateRequestPacket rcv = new FramebufferUpdateRequestPacket(buffer);

                Assert.AreEqual(200, rcv.Position.X, "X-position corrupted");
                Assert.AreEqual(300, rcv.Position.Y, "Y-position corrupted");

                Assert.AreEqual(100, rcv.Size.Width, "Width of the request area is corrupted");
                Assert.AreEqual(50, rcv.Size.Height, "Height of the request area is corrupted");

                Assert.AreEqual(4, rcv.Incremental, "The incremental request number is corrupted");
            }

            {
                FramebufferUpdateRequestPacket snd = new FramebufferUpdateRequestPacket(5, new Coords(400, 200), new Size(200, 150));

                byte[] buffer = snd.Serialize();

                FramebufferUpdateRequestPacket rcv = new FramebufferUpdateRequestPacket(buffer);

                Assert.AreEqual(400, rcv.Position.X, "X-position corrupted");
                Assert.AreEqual(200, rcv.Position.Y, "Y-position corrupted");

                Assert.AreEqual(200, rcv.Size.Width, "Width of the request area is corrupted");
                Assert.AreEqual(150, rcv.Size.Height, "Height of the request area is corrupted");

                Assert.AreEqual(5, rcv.Incremental, "The incremental request number is corrupted");
            }

        }

        [TestMethod]
        public void TestFramebufferUpdateResponse()
        {

            RectangleInfo RectInfo1 = new RectangleInfo(new Coords(100, 100), new Size(50, 100), EncodingType.BitMap, Encoding.ASCII.GetBytes("ciao"));
            RectangleInfo RectInfo2 = new RectangleInfo(new Coords(200, 50), new Size(150, 20), EncodingType.Jpeg, Encoding.ASCII.GetBytes("asdasd"));

            FramebufferUpdateResponsePacket snd = new FramebufferUpdateResponsePacket(new RectangleInfo[] { RectInfo1, RectInfo2 });

            byte[] buffer = snd.Serialize();

            FramebufferUpdateResponsePacket rcv = new FramebufferUpdateResponsePacket(buffer);

            Assert.AreEqual(100, rcv.Rectangles[0].Coords.X, "Rectangle[0] X-position corrupted");
            Assert.AreEqual(100, rcv.Rectangles[0].Coords.Y, "Rectangle[0] Y-position corrupted");

            Assert.AreEqual(200, rcv.Rectangles[1].Coords.X, "Rectangle[1] X-position corrupted");
            Assert.AreEqual(50, rcv.Rectangles[1].Coords.Y, "Rectangle[1] Y-position corrupted");

            Assert.AreEqual(50, rcv.Rectangles[0].Size.Width, "Rectangle[0] Width corrupted");
            Assert.AreEqual(100, rcv.Rectangles[0].Size.Height, "Rectangle[0] Height corrupted");

            Assert.AreEqual(150, rcv.Rectangles[1].Size.Width, "Rectangle[1] Width corrupted");
            Assert.AreEqual(20, rcv.Rectangles[1].Size.Height, "Rectangle[1] Height corrupted");

            Assert.AreEqual(EncodingType.BitMap, rcv.Rectangles[0].Encoding, "Rectangle[0] Encoding type corrupted");
            Assert.AreEqual(EncodingType.Jpeg, rcv.Rectangles[1].Encoding, "Rectangle[1] Encoding type corrupted");

            Assert.AreEqual("ciao", Encoding.ASCII.GetString(rcv.Rectangles[0].Data), "Rectangle[0] Data corrupted");
            Assert.AreEqual("asdasd", Encoding.ASCII.GetString(rcv.Rectangles[1].Data), "Rectangle[1] Data corrupted");
            

        }

        [TestMethod]
        public void TestProtocolVersion()
        {

            ProtocolVersionPacket snd = new ProtocolVersionPacket("000.001");

            byte[] buffer = snd.Serialize();

            ProtocolVersionPacket rcv = new ProtocolVersionPacket(buffer);

            Assert.IsTrue(snd.Version == rcv.Version, "Version number corrupted");

        }


    }
}
